package cn.csq;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @author <a href="mailto:csq02198031@alibaba-inc.com">chengshanqing</a>
 * @date 2025/8/20 11:27
 */
public class SingletonPatternTest {
    // 用其他方式获取实例 全局只有一个

    public static void main(String[] args) {
        A a = new A() {

        };


    }
}


class A {

    public A() {

    }


}

class B {

    private static B b = new B();

    private B() {

    }

    public static B getInstance() {
        return b;
    }

}

// 饿汉式 使用才创建
class C {

    private static C c = null;

    private C() {

    }

    // 非线程安全 两个线程都判断为空，都会创建 需要加锁
    public static C getInstance() {
        if (c == null) {
            c = new C();
        }
        return c;
    }

}

// 饿汉式 使用才创建 线程安全
class D {

    private static D d = null;

    private D() {

    }

    // 非线程安全 两个线程都判断为空，都会创建 需要加锁
    public synchronized static D getInstance() {
        if (d == null) {
            d = new D();
        }
        return d;
    }

}

// 饿汉式 使用才创建 线程安全  锁一部分
class E {

    // 防止指令重排
    private volatile static E e = null;

    private E() {

    }

    // 非线程安全 两个线程都判断为空，都会创建 需要加锁
    public static E getInstance() {
        if (e == null) {
            // instance = new Singleton() 是三步骤，分配内存空间、初始化对象、赋值指针
            synchronized (E.class) {
                e = new E();
            }
        }
        return e;
    }
    // 使用了volatile关键字后，可以保证有序性，指令重排序被禁止；
    // volatile还可以保证可见性，Java内存模型会确保所有线程看到的变量值是一致的。

}
// 静态内部类
class StaticInnerSingletonClass {
    private StaticInnerSingletonClass() {

    }

    private static class InnerNew {
        private static final StaticInnerSingletonClass instance = new StaticInnerSingletonClass();
    }

    public static StaticInnerSingletonClass getInstance() {
        return InnerNew.instance;
    }
}


class Singleton_6{
    // cas

    // 线程安全
    private static final AtomicReference<Singleton_6> instance = new AtomicReference<Singleton_6>();

    private Singleton_6() {

    }

    public static final Singleton_6 getInstance() {

        while(true){
            Singleton_6 singleton6 = instance.get();
            if (singleton6 == null) {
                instance.compareAndSet(null, new Singleton_6());
            }
            return instance.get();
        }
    }

}


enum Singleton_7{
    INSTANCE;

    public void anyMethod() {
        System.out.println("instance = " + INSTANCE);
    }

}
